/*
 * BarcodeTypeDAO.java
 *
 * $Id: BarcodeTypeDAO.java,v 1.2 2009-03-02 15:31:23 mario Exp $
 */
package org.ceteca.explica.server.common.dao;

import java.util.ArrayList;
import java.util.List;

import org.ceteca.explica.core.ExplicaException;
import org.ceteca.explica.core.InterfaceErrors;
import org.ceteca.explica.core.util.OperationResult;
import org.ceteca.explica.core.util.ResultMessage;
import org.ceteca.explica.core.common.BarcodeTypeOT;
import org.ceteca.explica.server.ServerContext;
import org.ceteca.explica.server.util.db.CriteriaBean;
import org.ceteca.explica.server.util.db.HibernateUtil;
import org.ceteca.explica.server.util.db.SQLGenerator;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * This class implements the barcode type data access object. It's 
 * a part of the data access layer and gives access to the database data. 
 * It knows the database structure and implementation. 
 * <br/>
 * This class is implemented to access a PostgreSQL database implementation.
 * <br/>
 * Responsibilities:
 * <li>
 * 	<ul> Provide statements for inserting new barcode types into the database. </ul>
 *  <ul> Provide statements for updating barcode types into the database. </ul>
 *  <ul> Provide statements for deleting barcode types from the database. </ul>
 *  <ul> Provide the database queries needed for barcode types operations.  </ul>
 * </li>
 */

public class BarcodeTypeDAO {
	
	/**
	 * Default constructor of the BarcodeTypeDAO class.
	 */
	public BarcodeTypeDAO() {
	}
	
	/**
	 * Query the database to get all the available barcode types. 
	 * @throws Exception, in case any error take place during
	 * the query operation.
	 * @return ArrayList, list of all the barcode types.
	 */
	public List getAllBarcodeTypes() throws Exception {
		List result = new ArrayList();
		// Open a new Hibernate session to query the Database
		Session session = HibernateUtil.getSessionFactory().openSession();
		
        try {
        	// Load the objects
        	result = session.createQuery(
            "from BarcodeTypeOT b")
            .list();

            System.out.println( "Consulta realizada! " +
            		result == null || result.size() <= 0?(" No se ha encontrado ningún barcode type!"):
            		("Se han encontrado: " + result.size() + " barcode types"));
        }
        catch (HibernateException ex) {
        	ResultMessage msg = ServerContext.getInstance().getMsgCatalog().
        		newResultMessage(InterfaceErrors.ERR_BARCODETYPE_NOT_FOUND, ex);
        	throw new ExplicaException(msg);
        }
        
        // Close the Hibernate session
        session.close();	
        
        // Return the result of the query
        return result;
	}
	
	/**
	 * Query (by primary key) the database to get a barcode type data. 
	 * @param idBarcodeType long, Internal id of the barcode type.
	 * @throws ExplicaException, in case any error take place during
	 * the query operation.
	 * @return BarcodeTypeOT, barcode type if it exists, null in any other case.
	 */
	public BarcodeTypeOT getBarcodeType(long idBarcodeType) throws ExplicaException {
		BarcodeTypeOT result = null;
		// Open a new Hibernate session to query the Database
		Session session = HibernateUtil.getSessionFactory().openSession();

        try {
        	// Load the object by the primary key (idResource)
        	result = (BarcodeTypeOT)session.get(BarcodeTypeOT.class, new Long(idBarcodeType));

            System.out.println( "Consulta realizada! " +
            		result == null?(" No se ha encontrado ningún barcode type correspondiente!"):
            		("Se ha encontrado el barcode type: " + result.getDescription()));
        }
        catch (HibernateException ex) {
        	ArrayList lParams = new ArrayList();
        	lParams.add("" + idBarcodeType);
        	ResultMessage msg = ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_BARCODETYPE_NOT_FOUND, ex, lParams);
        	throw new ExplicaException(msg);
        }
        
        // Close the Hibernate session
        session.close();	
        
        // Return the result of the query
        return result;
	}
	
	/**
	 * Query the database to get a barcode type data. 
	 * @param description String, barcode type description.
	 * @throws ExplicaException, in case any error take place during
	 * the query operation.
	 * @return BarcodeTypeOT, barcode type if it exists, null in any other case.
	 */
	public BarcodeTypeOT getBarcodeType(String description) throws ExplicaException {
		BarcodeTypeOT result = null;
		// Open a new Hibernate session to query the Database
		Session session = HibernateUtil.getSessionFactory().openSession();

        try {
        	// Build the query statement
        	String sql = "FROM BarcodeTypeOT b WHERE b.description=?";
        	Query q = session.createQuery(sql);
        	q.setString(0, description);

        	// Run the query statement
        	result = (BarcodeTypeOT)q.uniqueResult();

            System.out.println( "Consulta realizada! " +
            		result == null?(" No se ha encontrado ningún barcode type correspondiente!"):
            		("Se ha encontrado el barcode type: " + result.getDescription()));
        }
        catch (HibernateException ex) {
        	ArrayList lParams = new ArrayList();
        	lParams.add("" + description);
        	ResultMessage msg = ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_BARCODETYPE_NOT_FOUND, ex, lParams);
        	throw new ExplicaException(msg);
        }
        
        // Close the Hibernate session
        session.close();	
        
        // Return the result of the query
        return result;
	}
	
	/**
	 * Query the database to get a list of barcode types that math
	 * the query criteria specified. 
	 * @param lCriteria ArrayList<CriteriaBean>, list of query criteria.
	 * @throws ExplicaException, in case any error take place during
	 * the query operation.
	 * @return ArrayList<BarcodeTypeOT>, list of barcode types matching the 
	 * searching criteria.
	 */
	public ArrayList<BarcodeTypeOT> getBarcodeTypes(ArrayList<CriteriaBean> lCriteria) throws ExplicaException {
		ArrayList<BarcodeTypeOT> result = null;
		// Open a new Hibernate session to query the Database
		Session session = HibernateUtil.getSessionFactory().openSession();

        try {
        	// Build the query statement
        	SQLGenerator sqlGen = new SQLGenerator();

        	Criteria crit = sqlGen.getSQLCriteria(session, BarcodeTypeOT.class, lCriteria);
        	
        	// Run the query statement
        	result = (ArrayList)crit.list();

            System.out.println( "Consulta realizada! " +
            		result == null?(" No se ha encontrado ningún barcode type correspondiente!"):
            		("Se han encontrado barcode types: " + result.size()));
        }
        catch (HibernateException ex) {
        	ResultMessage msg = ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_BARCODETYPE_NOT_FOUND, ex, null);
        	throw new ExplicaException(msg);
        }
        
        // Close the Hibernate session
        session.close();	
        
        // Return the result of the query
        return result;
	}
	
	public OperationResult delBarcodeType(Long idBarcodeType) throws ExplicaException {
		OperationResult result = new OperationResult();

		if (idBarcodeType == null) {
			result.addResultMessage(OperationResult.RESULT_ERROR, 
					ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_BARCODETYPE_DELETE_NULL));
		}
		else {
	
			// Build the list of parameters for the localized operation result message.
			ArrayList lParams = new ArrayList();
			lParams.add(idBarcodeType);
		
			// Open a new Hibernate session to query the Database
			Session session = HibernateUtil.getSessionFactory().openSession();
	
	    	// Open a new transaction
	        Transaction tx = session.beginTransaction();
	
	        // Delete the barcode type from the database
	        try {
	        	BarcodeTypeOT barcodeType = (BarcodeTypeOT)session.load(BarcodeTypeOT.class, idBarcodeType);
	        	System.out.println("Barcode Type (" + barcodeType.getIdBarcodeType() + ") found: " + barcodeType.getDescription());
	        	session.delete(barcodeType);
	        	tx.commit();
	        	
	        	lParams.add(idBarcodeType);
	        	
	        	System.out.println("BarcodeType (" + barcodeType.getIdBarcodeType() + ") deleted: " + barcodeType.getDescription());
	        	result.addResultMessage(OperationResult.RESULT_OK, 
	        			ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.MSG_BARCODETYPE_DELETE_OK, lParams));
	        }
	        catch (HibernateException ex) {
	        	ex.printStackTrace();
	        	tx.rollback();
	        	
	        	ResultMessage msg = ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_BARCODETYPE_DELETE, ex, lParams);
	        	throw new ExplicaException(msg);
	        }
	        
	        // Close the Hibernate session
	        session.close();
	        
	        System.out.println("Session closed!");
		} // else product!=null
        
        return result;
	}
	
	public OperationResult delBarcodeTypes(ArrayList<Long> lSelBarcodeTypes) throws ExplicaException {
		OperationResult result = new OperationResult();
		
        try {
        	// Build the query statement
        	for (int i=0; lSelBarcodeTypes != null && i<lSelBarcodeTypes.size(); i++) {
        		// Delete the barcode type
        		result.add(this.delBarcodeType(lSelBarcodeTypes.get(i)));
        	} // for each barcode type
        }
        catch (HibernateException ex) {
        	ex.printStackTrace();
        	
        	ResultMessage msg = ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_BARCODETYPE_DELETE, ex, null);
        	throw new ExplicaException(msg);
        }
        
        return result;
	}
	
	public OperationResult saveBarcodeType(BarcodeTypeOT barcodeType) throws ExplicaException {
		OperationResult result = new OperationResult();

		if (barcodeType == null) {
			result.addResultMessage(OperationResult.RESULT_ERROR, 
					ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_BARCODETYPE_SAVE_NULL));
		}
		else {
	
			// Build the list of parameters for the localized operation result message.
			ArrayList lParams = new ArrayList();
			lParams.add(barcodeType.getDescription());
		
			// Open a new Hibernate session to query the Database
			Session session = HibernateUtil.getSessionFactory().openSession();
	
	    	// Open a new transaction
	        Transaction tx = session.beginTransaction();
	
	        // Delete the barcode type from the database
	        try {
	        	session.saveOrUpdate(barcodeType);
	        	tx.commit();
	        	
	        	lParams.add(barcodeType.getIdBarcodeType());
	        	
	        	System.out.println("BarcodeType (" + barcodeType.getIdBarcodeType() + ") saved: " + barcodeType.getDescription());
	        	result.addResultMessage(OperationResult.RESULT_OK, 
	        			ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.MSG_BARCODETYPE_SAVE_OK, lParams));
	        }
	        catch (HibernateException ex) {
	        	ex.printStackTrace();
	        	tx.rollback();
	        	
	        	ResultMessage msg = ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_BARCODETYPE_SAVE, ex, lParams);
	        	throw new ExplicaException(msg);
	        }
	        
	        // Close the Hibernate session
	        session.close();
	        
	        System.out.println("Session closed!");
		} // else product!=null
        
        return result;
	}
	
	/**
	 * Returns tag Id assigned to CVS source file.
	 */
	public static String getRevision() {
		return "$Id: BarcodeTypeDAO.java,v 1.2 2009-03-02 15:31:23 mario Exp $";
	}
}
